import { Vector2 } from '../../types/MathTypes';
import { TimelineState } from '../../types/TimelineTypes';

/**
 * SceneElement Abstract Class
 * 
 * Base class for all scene elements.
 */
export abstract class SceneElement {
  protected id: string;
  protected position: Vector2;
  protected scale: Vector2;
  protected rotation: number;
  protected visible: boolean;
  protected zIndex: number;

  /**
   * Creates an instance of SceneElement.
   * @param id - Unique identifier
   * @param position - Position coordinates (x, y)
   * @param scale - Scale factors (x, y)
   * @param rotation - Rotation in degrees
   * @param visible - Visibility flag
   * @param zIndex - Z-order for rendering
   */
  constructor(
    id: string,
    position: Vector2 = { x: 0, y: 0 },
    scale: Vector2 = { x: 1, y: 1 },
    rotation: number = 0,
    visible: boolean = true,
    zIndex: number = 0
  ) {
    this.id = id;
    this.position = position;
    this.scale = scale;
    this.rotation = rotation;
    this.visible = visible;
    this.zIndex = zIndex;
  }

  /**
   * Gets the element ID
   * @returns string - The element ID
   */
  public getId(): string {
    return this.id;
  }

  /**
   * Gets the element position
   * @returns Vector2 - The position coordinates
   */
  public getPosition(): Vector2 {
    return this.position;
  }

  /**
   * Sets the element position
   * @param position - New position coordinates
   */
  public setPosition(position: Vector2): void {
    this.position = position;
  }

  /**
   * Gets the element scale
   * @returns Vector2 - The scale factors
   */
  public getScale(): Vector2 {
    return this.scale;
  }

  /**
   * Sets the element scale
   * @param scale - New scale factors
   */
  public setScale(scale: Vector2): void {
    this.scale = scale;
  }

  /**
   * Gets the element rotation
   * @returns number - The rotation in degrees
   */
  public getRotation(): number {
    return this.rotation;
  }

  /**
   * Sets the element rotation
   * @param rotation - New rotation in degrees
   */
  public setRotation(rotation: number): void {
    this.rotation = rotation;
  }

  /**
   * Checks if the element is visible
   * @returns boolean - Visibility flag
   */
  public isVisible(): boolean {
    return this.visible;
  }

  /**
   * Sets the element visibility
   * @param visible - New visibility flag
   */
  public setVisible(visible: boolean): void {
    this.visible = visible;
  }

  /**
   * Gets the element z-index
   * @returns number - The z-order for rendering
   */
  public getZIndex(): number {
    return this.zIndex;
  }

  /**
   * Sets the element z-index
   * @param zIndex - New z-order for rendering
   */
  public setZIndex(zIndex: number): void {
    this.zIndex = zIndex;
  }

  /**
   * Renders the element
   * @param canvasContext - The canvas context to render to
   */
  public abstract render(canvasContext: any): void;

  /**
   * Updates the element based on timeline state
   * @param timelineState - The current timeline state
   */
  public abstract update(timelineState: TimelineState): void;
}